package com.jse;

import java.awt.AWTException;
import java.awt.Color;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.util.Arrays;
import java.util.Base64;
import java.util.ServiceLoader;

import javax.imageio.ImageIO;
import javax.sound.midi.ShortMessage;
import javax.sound.midi.spi.MidiDeviceProvider;
import javax.sound.sampled.AudioFileFormat.Type;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;

public class Awts {
	
	public static Robot robot;
	static {
		ImageIO.setUseCache(false);
		try {
			robot=new Robot();
		} catch (AWTException e) {
			e.printStackTrace();
		}
	}
	public static Clipboard clipboard(){return Toolkit.getDefaultToolkit().getSystemClipboard();}
	public static Toolkit tookit() {return Toolkit.getDefaultToolkit();}
	public static Desktop desktop() {return Desktop.getDesktop();}
	
	public static void browser(URI uri) throws IOException {desktop().browse(uri);}
	public static void termination(boolean enable) throws IOException {
		if(enable)desktop().enableSuddenTermination();else desktop().disableSuddenTermination();
	}
	public static void edit(String file) throws IOException {desktop().edit(new File(file));}
	public static void open(String file) throws IOException {desktop().open(new File(file));}
	public static void print(String file) throws IOException {desktop().print(new File(file));}
	public static void mail(String uri) throws IOException {desktop().mail(URI.create(uri));}
	public static void recycle(String f) throws IOException {desktop().moveToTrash(new File(f));}

	public static Color randomColor() {return new Color(Lang.rand(255),Lang.rand(255),Lang.rand(255));}

	public static Color randomColor(int b,int e){return new Color(Lang.rand(b, e),Lang.rand(b,e),Lang.rand(b, e));}
	
	public static String rgb(Color color){return "rgb(%d, %d, %d)".formatted(color.getRed(),color.getGreen(),color.getBlue());}
	
	public static Color color(String m) {
		if(m.charAt(0)=='#') {
			return Color.decode(m);
		}else if(m.indexOf(",")!=-1) {
			var rgb=m.split(",");
			return new Color(Integer.valueOf(rgb[0]),Integer.valueOf(rgb[1]),Integer.valueOf(rgb[2]));
		}
		return Color.getColor(m);
	}
	
	public static void captcha(String code,OutputStream out) throws IOException {
		int width=code.length()*40,height=45;//字体宽度高度
		var img=new BufferedImage(width,height, BufferedImage.TYPE_INT_RGB);
		var g=img.createGraphics();//图形
		g.setBackground(Color.WHITE);g.fillRect(0, 0, img.getWidth(),img.getHeight());//填充背景白
		for (int i = 0; i <50; i++) {
		g.setColor(randomColor());
		g.drawOval(Lang.rand(width),Lang.rand(height),Lang.rand(height >> 1),Lang.rand(height >> 1));
		}
		g.setFont(new Font(Font.DIALOG, Font.PLAIN,45));
		g.drawString(code,10,40);//g.fillArc(130,155,100,75,0,270);//画圆 g.draw(new Area());//画正方形
		g.dispose();
		ImageIO.write(img,"jpg",out);
	}
	
	/**
	 * 
	 * @param source 要添加的图片
	 * @param text 添加的文字 #2e8b57 或 255,255,0
	 * @param color 添加的颜色 
	 * @param fontSize
	 * @param x
	 * @param y
	 * @throws IOException
	 */
	public static void watermark(String source,String text,String color,int fontSize,int x,int y) throws IOException {
		final BufferedImage targetImg = ImageIO.read(new File(source));
		int width = targetImg.getWidth(); //图片宽
        int height = targetImg.getHeight(); //图片高
        BufferedImage bufferedImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_BGR);
        var g = bufferedImage.createGraphics();
        g.drawImage(targetImg, 0, 0, width, height, null);
        g.setColor(Color.getColor(color)); //水印颜色
        g.setFont(new Font("微软雅黑",Font.ITALIC,fontSize));
        g.drawString(text, x, y);
        FileOutputStream outImgStream = new FileOutputStream(source+".jpg");
        ImageIO.write(bufferedImage,"jpg",outImgStream);
        outImgStream.flush();
        outImgStream.close();
        g.dispose();
	}
	
	public static void scale(String source,int width,int height) throws IOException {
		final BufferedImage originalImage = ImageIO.read(new File(source));
		Image resultingImage = originalImage.getScaledInstance(width, height, Image.SCALE_AREA_AVERAGING);
        BufferedImage outputImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        outputImage.getGraphics().drawImage(resultingImage, 0, 0, null);
        ImageIO.write(outputImage, "jpg",new FileOutputStream(source));
	}
	public static void scale(String source,double percentage) throws IOException {
		final BufferedImage originalImage = ImageIO.read(new File(source));
		int width=(int)(originalImage.getWidth()*percentage);
		int height=(int)(originalImage.getHeight()*percentage);
		Image resultingImage = originalImage.getScaledInstance(width, height, Image.SCALE_AREA_AVERAGING);
        BufferedImage outputImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        outputImage.getGraphics().drawImage(resultingImage, 0, 0, null);
        ImageIO.write(outputImage, "jpg",new FileOutputStream(source));
	}
	public static void cut(String source,double percentage) throws IOException {
		final BufferedImage originalImage = ImageIO.read(new File(source));
		int width=(int)(originalImage.getWidth()*percentage);
		int height=(int)(originalImage.getHeight()*percentage);
		Image resultingImage = originalImage.getScaledInstance(width, height, Image.SCALE_AREA_AVERAGING);
        BufferedImage outputImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        outputImage.getGraphics().drawImage(resultingImage, 0, 0, null);
        ImageIO.write(outputImage, "jpg",new FileOutputStream(source));
	}
	public static void screen(String out) throws AWTException, IOException {
		Dimension d=  tookit().getScreenSize();//获取屏幕分辨率
        Rectangle screenRect=new  Rectangle(d);//创建该分辨率的矩形对象
        BufferedImage  bufferedImage=robot.createScreenCapture(screenRect);//根据这个矩形截图
        ImageIO.write(bufferedImage,"png",new File(out));//保存截图
	}
	
	public static void main(String[] args) throws IOException, AWTException, LineUnavailableException {
		ShortMessage m=new ShortMessage();
//		MidiDevice.Info info=
		javax.sound.midi.Synthesizer s;
		ServiceLoader<MidiDeviceProvider> mps=ServiceLoader.load(MidiDeviceProvider.class);
		MidiDeviceProvider mp=mps.findFirst().get();
		System.out.println(Arrays.toString(mp.getDeviceInfo()));
		final AudioFormat af = new AudioFormat(8000, 16, 1, true, true);
		SourceDataLine line = AudioSystem.getSourceDataLine(af);
		line.open(af);
        line.start();
		byte[] bs=generateSineWavefreq(1000,2);
		line.write(bs, 0, bs.length);
		line.drain();
		
		AudioInputStream ais=new AudioInputStream(new ByteArrayInputStream(bs),af,bs.length
				);
		AudioSystem.write(ais, Type.WAVE, new File("d:/1.wav"));
	}
	
	private static byte[] generateSineWavefreq(int frequencyOfSignal, int seconds) {
        // total samples = (duration in second) * (samples per second)
        byte[] sin = new byte[seconds * 8000];
        double samplingInterval = (double) (8000 / frequencyOfSignal);
        System.out.println("Sampling Frequency  : "+8000);
        System.out.println("Frequency of Signal : "+frequencyOfSignal);
        System.out.println("Sampling Interval   : "+samplingInterval);
        for (int i = 0; i < sin.length; i++) {
            double angle = (2.0 * Math.PI * i) / samplingInterval;
            sin[i] = (byte) (Math.sin(angle) * 127);
            //System.out.println("" + sin[i]);
        }
        return sin;
    }
	
	public static String base64(InputStream in, String type) {
			try(in){
				BufferedImage img= ImageIO.read(in);
				ByteArrayOutputStream out=new ByteArrayOutputStream();
				ImageIO.write(img, type,ImageIO.createImageOutputStream(out));
				return Base64.getEncoder().encodeToString(out.toByteArray()).replace(" ", "+");
			} catch (Exception e) {
				throw new RuntimeException("obj:{} is not support case to type:{} base64!");
			}
	}
}
